#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
菜单界面模块
提供交互式命令行菜单
"""

import sys
from typing import Dict, Callable, List, Tuple

from .utils import logger
from ..database.postgresql_manager import PostgresqlManager
from ..pool.pgpool_manager import PgpoolManager
from ..pool.pgbouncer_manager import PgBouncerManager
from ..replication.repmgr_manager import RepmgrManager
from ..system.system_manager import SystemManager
from ..monitoring.monitoring import PostgresqlMonitorManager
from ..monitoring.performance_test import PostgresqlPerformanceManager
from ..monitoring.pgbench_test import PgbenchManager
from . import config
from .ui_utils import print_title, get_input, confirm, create_menu_table, console, print_success, print_error, print_warning

class Menu:
    """交互式命令行菜单类"""
    
    def __init__(self):
        self.pg_manager = PostgresqlManager()
        self.pgpool_manager = PgpoolManager()
        self.pgbouncer_manager = PgBouncerManager()
        self.repmgr_manager = RepmgrManager()
        self.system_manager = SystemManager()
        self.monitoring_manager = PostgresqlMonitorManager()
        self.performance_manager = PostgresqlPerformanceManager()
        self.pgbench_manager = PgbenchManager()
        
        # 菜单选项与对应的功能函数映射
        self.options = {
            # PostgreSQL操作
            "1": self.pg_manager.install,
            "2": self.pgpool_manager.install,
            "3": self.pg_manager.uninstall,
            "4": self.pgpool_manager.uninstall,
            "5": self.pg_manager.start,
            "6": self.pg_manager.stop,
            "7": self.pg_manager.restart,
            "8": self.pg_manager.reload,
            "9": self.pgpool_manager.start,
            "10": self.pgpool_manager.stop,
            "11": self.pgpool_manager.restart,
            "12": self.pgpool_manager.reload,
            "13": self.pg_manager.show_config,
            "14": self.pgpool_manager.show_config,
            "15": self.pg_manager.backup,
            "16": self.pg_manager.restore,
            "17": self.pg_manager.pull_backup_from_master,
            "18": self.pg_manager.status,
            "19": self.pg_manager.show_connections,
            "20": self.pg_manager.create_database_and_user,
            "21": self.pg_manager.vacuum_database,
            "22": self.pg_manager.reindex_database,
            "23": self.pg_manager.enable_pg_stat_statements,
            "24": self.pg_manager.show_query_performance,
            "25": self.pgpool_manager.status,
            "26": self.pg_manager.change_replica_master_ip,
            "27": self.pg_manager.change_postgres_password,
            "28": self.pg_manager.create_replicator_user,
            "29": self.pg_manager.show_all_users,
            "30": self.pg_manager.delete_user,
            "31": self.pg_manager.show_master_replication_status,
            "32": self.pg_manager.show_slave_replication_status,
            "33": self.system_manager.generate_and_sync_ssh_key,
            "34": self.repmgr_manager.install_repmgr,
            "35": self.repmgr_manager.create_repmgr_user_and_db,
            "36": self.repmgr_manager.create_repmgr_config,
            "37": self.repmgr_manager.register_primary_node,
            "38": self.repmgr_manager.register_standby_node,
            "39": self.repmgr_manager.hand_switchover,
            "40": self.repmgr_manager.handle_old_primary_recovery,
            "41": self.repmgr_manager.show_cluster,
            "42": self.repmgr_manager.clone_standby,
            "43": self.repmgr_manager.create_sudoers_file,
            "44": self.repmgr_manager.repmgr_nodestatus,
            "45": self.repmgr_manager.standby_follow,
            "46": self.repmgr_manager.standby_promote,
            "47": self.repmgr_manager.create_repmgrd_service,
            "48": self.repmgr_manager.repair_repmgr_extension,
            "49": self.repmgr_manager.regist_witness_node,
            "50": self.pg_manager.create_new_cluster,
            "51": self.pg_manager.fix_shared_memory_issue,
            "52": self.system_manager.add_ssh_config,
            "53": self.pgpool_manager.pcp_attach_node,
            "54": self.pgpool_manager.pcp_detach_node,
            "55": self.pgpool_manager.create_pcp_pass_and_update_conf,
            "56": self.pg_manager.add_ip_to_pghba,
            "57": self.pg_manager.create_pgpass_file,
            "58": self.pg_manager.incremental_backup,
            "59": self.monitoring_manager.start_monitoring,
            "60": self.performance_manager.start_performance_test,
            
            # PgBouncer操作
            "61": self.pgbouncer_manager.install,
            "62": self.pgbouncer_manager.uninstall,
            "63": self.pgbouncer_manager.start,
            "64": self.pgbouncer_manager.stop,
            "65": self.pgbouncer_manager.restart,
            "66": self.pgbouncer_manager.reload,
            "67": self.pgbouncer_manager.status,
            "68": self.pgbouncer_manager.show_config,
            "69": self.pgbouncer_manager.optimize_config,
            "70": self.pgbouncer_manager.add_database,
            "71": self.database_management,
            "72": self.pg_manager.sync_sequence,
            "73": self.pg_manager.optimize_postgresql_config,
            "74": self.pg_manager.show_current_config,
            "75": self.pg_manager.restore_config,
            "76": self.pgbench_manager.start_pgbench_test,
            
            "0": self.exit_program
        }
    
    def display_menu(self):
        """显示菜单界面"""
        # 显示标题和版本
        print_title(f"优纪数据库懒人脚本 V{config.VERSION}")
        
        # 欢迎图标
        console.print("""
        ██╗   ██╗ ██████╗ ██╗   ██╗     ██╗██╗
        ╚██╗ ██╔╝██╔═══██╗██║   ██║     ██║██║
         ╚████╔╝ ██║   ██║██║   ██║     ██║██║
          ╚██╔╝  ██║   ██║██║   ██║██   ██║██║
           ██║   ╚██████╔╝╚██████╔╝╚█████╔╝██║
           ╚═╝    ╚═════╝  ╚═════╝  ╚════╝ ╚═╝
        """, style="bright_blue")
        
        # PostgreSQL操作菜单
        pg_options = [
            ("1", "安装最新 PostgreSQL"),
            ("3", "卸载 PostgreSQL"),             
            ("5", "启动 PostgreSQL"),    
            ("6", "停止 PostgreSQL"),    
            ("7", "重启 PostgreSQL"),   
            ("8", "重载 PostgreSQL"),   
            ("13", "PostgreSQL 配置文件路径"), 
            ("15", "完整备份 PostgreSQL 数据库"),
            ("58", "增量备份 PostgreSQL 数据库"),
            ("16", "恢复 PostgreSQL 数据库"),
            ("17", "从主库拉取备份数据"),
            ("18", "PostgreSQL 状态"),
            ("19", "查看当前活动的数据库连接"),
            ("20", "创建数据库和用户"),
            ("71", "删除/清空数据库"),
            ("72", "同步指定表的ID序列"),
            ("21", "数据库清理VACUUM"),
            ("22", "数据库重建索引"),
            ("23", "数据库启用性能监控扩展"),
            ("24", "显示数据库性能监控"),
            ("26", "修改从库指向主库IP"),
            ("27", "修改数据库用户密码"),
            ("28", "创建流复制用户"),
            ("29", "查看当前数据库所有用户"),
            ("30", "删除数据库指定用户"),
            ("31", "查看主库流复制状态"),
            ("32", "查看从库流复制状态"),
            ("43", "一键给与postgres用户root权限"),
            ("50", "修改数据库默认目录为指定目录"),
            ("51", "修复postgresql共享内存段错误"),
            ("56", "一键添加信任授权pg_hba.conf"),
            ("57", "为当前客户端创建数据库免输入密码配置文件(.pgpass)"),
            ("59", "启动实时监控仪表板"),
            ("60", "运行数据库性能测试"),
            ("76", "运行pgbench性能测试"),
            ("73", "一键优化PostgreSQL配置"),
            ("74", "显示当前PostgreSQL配置"),
            ("75", "恢复PostgreSQL配置备份")
        ]
        
        # Pgpool操作菜单
        pgpool_options = [
            ("2", "安装最新 Pgpool"),
            ("4", "卸载 Pgpool"),
            ("9", "启动 Pgpool"),
            ("10", "停止 Pgpool"),
            ("11", "重启 Pgpool"),
            ("12", "重载 Pgpool"),
            ("14", "Pgpool 配置文件路径"),
            ("25", "pgpool状态"),
            ("53", "pcp_attach"),  
            ("54", "pcp_detach"),
            ("55", "一键创建添加.pass/pcp.conf")
        ]
        
        # PgBouncer操作菜单
        pgbouncer_options = [
            ("61", "安装最新 PgBouncer"),
            ("62", "卸载 PgBouncer"),
            ("63", "启动 PgBouncer"),
            ("64", "停止 PgBouncer"),
            ("65", "重启 PgBouncer"),
            ("66", "重载 PgBouncer配置"),
            ("67", "查看 PgBouncer状态"),
            ("68", "显示配置文件路径"),
            ("69", "一键优化PgBouncer配置"),
            ("70", "添加数据库连接配置")
        ]
        
        # repmgr操作菜单
        repmgr_options = [
            ("34", "安装最新版本repmgr"),
            ("35", "创建rempgr超级用户和数据库"),
            ("36", "创建rempgr配置文件"),
            ("37", "注册主节点"),
            ("38", "注册从节点"),
            ("39", "手动主备切换,当前切换为主,主切换为备"),
            ("40", "裂脑同步处理"),
            ("41", "查看当前集群状态"),
            ("42", "从主库克隆数据到本节点"),
            ("44", "检查当前节点健康状态"),
            ("45", "手动更新当前节点跟随新主节点"),
            ("46", "升级当前数据库为主库(主节点无法访问才能执行)"),
            ("47", "一键创建repmgr服务并启动"),
            ("48", "修复repmgr扩展"),
            ("49", "注册见证节点")
        ]
        
        # 其他操作菜单
        other_options = [
            ("52", "为指定SSH链接修改默认链接端口"),
            ("33", "同步免登录公钥到指定服务器"),
            ("0", "退出程序")
        ]
        
        # 使用rich表格显示菜单选项
        console.print(create_menu_table("🍎PGSQL操作", pg_options))
        console.print(create_menu_table("🍌PGPOOL操作", pgpool_options))
        console.print(create_menu_table("🍐PGBOUNCER操作", pgbouncer_options))
        console.print(create_menu_table("🌰repmgr操作", repmgr_options))
        console.print(create_menu_table("🍿其他操作", other_options))
    
    def run(self):
        """运行菜单"""
        try:
            while True:
                self.display_menu()
                choice = get_input("请输入选项编号")
                
                # 检查选择的选项是否有效
                action = self.options.get(choice)
                if action:
                    try:
                        action()
                    except KeyboardInterrupt:
                        print_warning("\n操作已取消")
                    except Exception as e:
                        print_error(f"执行操作时出错: {e}")
                        logger.error(f"执行操作时出错: {e}")
                else:
                    print_error("选择无效，请重试")
                    
                # 询问是否继续
                if not confirm("\n是否继续?", default=True):
                    self.exit_program()
        except KeyboardInterrupt:
            self.exit_program()
        
    def database_management(self):
        """数据库删除/清空菜单"""
        console.print("\n--- 数据库管理 ---", style="bold green")
        console.print("1. 删除指定数据库")
        console.print("2. 删除数据库中的所有表（保留空数据库）")
        console.print("3. 清空指定表的数据（保留表结构）")
        console.print("0. 返回主菜单")
        
        choice = get_input("请选择操作")
        
        if choice == "1":
            self.pg_manager.drop_database()
        elif choice == "2":
            self.pg_manager.drop_all_tables()
        elif choice == "3":
            self.pg_manager.truncate_tables()
        elif choice == "0":
            return
        else:
            print_error("选择无效，请重试")
            
    def exit_program(self):
        """退出程序"""
        logger.info("退出程序")
        print_success("感谢使用，再见！")
        sys.exit(0) 